home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
pascal
/
tpl60n19.zip
/
TESTPRGS.ZIP
/
MAINVARS.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-02-27
|
18KB
|
581 lines
{$a+,n-,x-,s-,i-,r-,b-,v-}
unit mainvars;
interface
{ (C) Apr 19 1983 in BASIC version by:
Professor W M Kahan,
567 Evans Hall.
Electrical Engineering & Computer Science Dept.
University of California
Berkeley, California 94720
USA
converted to Pascal by:
B A Wichmann
National Physical Laboratory
Teddington Middx
TW11 OLW
UK
further massaging by dmg =
David M. Gay
AT&T Bell Labs
600 Mountain Avenue
Murray Hill, NJ 07974
and a couple of bug fixes from dgh = sun!dhough (29 May 1986)
See the article by Richard Karpinski in the February 1985 issue
of BYTE Magazine.
You may copy this program freely if you acknowledge its source.
Comments on the Pascal version to NPL or dmg, please. }
const
{integer constants}
NoTrials = 20;
{Number of tests for commutativity. }
type
Guard = (Yes, No);
Rounding = (Chopped, Rounded, Other);
Message = packed array [1..40] of char;
WhichOp = packed array [1..14] of char;
Class = (Flaw, Defect, SeriousDefect, Failure);
var
{input: text;}
{Small floating point constants.}
Zero, { 0.0; }
Half, { 0.5; }
One, { 1.0; }
Two, { 2.0; }
Three, { 3.0; }
Four, { 4.0; }
Five, { 5.0; }
Eight, { 8.0; }
Nine, { 9.0; }
TwentySeven, { 27.0; }
ThirtyTwo, { 32.0; }
TwoForty, { 240.0; }
MinusOne, { -1.0; }
OneAndHalf: { 1.5; } real;
MyZero: integer;
NoTimes, Index: integer;
ch: char;
AInverse, A1: real;
Radix, BInverse, RadixD2, BMinusU2: real;
C, CInverse: real;
D, FourD: real;
E0, E1, Exp2, MinSqrtError: real;
SqrtError, MaxSqrtError, E9: real;
Third: real;
F6, F9: real;
H, HInverse: real;
I: integer;
StickyBit, J: real;
M, N, N1: real;
Precision: real;
Q, Q9: real;
R, R9: real;
T, Underflow, S: real;
OneUlp, UnderflowThreshold, U1, U2: real;
V, V0, V9: real;
W: real;
X, X1, X2, X8, RandomNumber1: real;
Y, Y1, Y2, RandomNumber2: real;
Z, PseudoZero, Z1, Z2, Z9: real;
NoErrors: array [Class] of integer;
Milestone: integer;
PageNo: integer;
GMult, GDiv, GAddSub: Guard;
RMult, RDiv, RAddSub, RSqrt: Rounding;
Continue, Break, Done, NotMonot, Monot, AnomolousArithmetic, IEEE,
SquareRootWrong, UnderflowNotGradual: Boolean;
{ Computed constants. }
{U1 gap below 1.0, i.e, 1.0-U1 is next number below 1.0 }
{U2 gap above 1.0, i.e, 1.0+U2 is next number above 1.0 }
procedure Page;
function Int (X: real): real;
function Sign (X: real): real;
procedure Pause;
procedure Instructions;
procedure Heading;
procedure Characteristics;
procedure History;
procedure notify(T: WhichOp);
procedure TestCondition (K: Class; Valid: Boolean; T: Message);
function Random: real;
procedure SqrtXMinX (ErrorKind: Class);
procedure NewD;
procedure SubRout3750;
function Power (X, Y: real): real;
procedure DoesYequalX;
procedure SubRout3980;
procedure PrintIfNPositive;
procedure TestPartialUnderflow;
implementation
procedure Page;
begin
(* write(#$C) *) {FF in TURBO Pascal} writeln; writeln;
end;
function Int (X: real): real;
{ simulates BASIC INT-function, which is defined as:
INT(X) is the greatest integer value less than or
equal to X. }
function LargeTrunc (X: real): real;
var
start, acc, y, p: real;
trunced: integer; (* dgh *)
begin (* LargeTrunc *)
if abs (X) < maxint then begin
trunced := trunc(X);
LargeTrunc := trunced;
end
else
begin
start := abs (X);
acc := 0.0;
repeat
y := start;
p := 1.0;
while y > maxint - 1.0 do
begin
y := y / Radix;
p := p * Radix;
end;
trunced := trunc(y);
acc := acc + trunced * p;
start := start - trunced * p;
until start < 1.0;
if X < 0.0 then
LargeTrunc := - acc
else
LargeTrunc := acc
end;
end (* LargeTrunc *);
begin (* Int *)
if X > 0.0 then
Int := LargeTrunc (X)
else if LargeTrunc (X - 0.5) = X then
Int := X
else
Int := LargeTrunc (X) - 1;
end (* Int *);
function Sign (X: real): real;
begin (* Sign *)
if X < 0.0 then
Sign := - 1.0
else
Sign := + 1.0;
end (* Sign *);
procedure Pause;
var
ch: char;
begin (* Pause *)
writeln ('To continue, press any key and newline:');
readln (input);
while not eoln (input) do
read (input, ch);
Page;
write ('Diagnosis resumes after milestone no ', Milestone);
writeln (' Page: ', PageNo);
writeln;
Milestone := Milestone + 1;
PageNo := PageNo + 1;
end (* Pause *);
procedure Instructions;
begin (* Instructions *)
writeln ('Lest this program stop prematurely, ',
'i.e. before displaying');
writeln (' "END OF TEST",');
writeln ('try to persuade the computer NOT to',
' terminate execution whenever an');
writeln ('error like Over/Underflow or Division by Zero occurs,',
' but rather');
writeln ('to persevere with a surrogate value after, ',
' perhaps, displaying some');
writeln ('warning. If persuasion avails naught, don''t despair'
, ' but run this');
writeln ('program anyway to see how many milestones it passes,',
' and then');
writeln ('amend it to make further progress.');
writeln ('Answer questions with Y, y, N or n',
' (unless otherwise indicated).');
writeln;
end (* Instructions *);
procedure Heading;
begin (* Heading *)
writeln ('Users are invited to help debug and augment',
' this program so it will');
writeln ('cope with unanticipated and newly uncovered',
' arithmetic pathologies.');
writeln ('Please send suggestions and interesting results to');
writeln(' Richard Karpinski');
writeln(' Computer Center U-76');
writeln(' University of California');
writeln(' San Francisco, CA 94143-0704, USA');
writeln;
writeln('In doing so, please include the following information:');
writeln(' Version: 10 February 1989');
writeln(' Computer:'); writeln;
writeln(' Compiler:'); writeln;
writeln(' Optimization level:'); writeln;
writeln(' Other relevant compiler options:'); writeln;
end (* Heading *);
procedure Characteristics;
begin (* Characteristics *)
writeln (
'Running this program should reveal these characteristics');
writeln (' Radix = 1, 2, 4, 8, 10, 16, 100, 256, or ...');
writeln (' Precision = number of significant digits carried.');
writeln (' U2 = Radix/Radix^Precision = One Ulp (OneUlpnit in the');
writeln (' Last Place) of 1.000xxx .');
writeln (' U1 = 1/Radix^Precision = One Ulp of numbers',
' a little less than 1.0 .');
writeln (' Adequacy of guard digits for Mult., Div., and Subt.');
writeln (' Whether arithmetic is chopped, correctly rounded, ',
'or something else');
writeln (' for Mult., Div., Add/Subt. and Sqrt.');
writeln (' Whether a Sticky Bit is used correctly for rounding.');
wr